//package com.coldlz.mmp.proxy.handlerserver;
//
//import com.coldlz.mmp.proxy.*;
//import io.netty.buffer.ByteBuf;
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.channel.ChannelInboundHandlerAdapter;
//import io.netty.channel.ChannelPipeline;
//import io.netty.handler.codec.http.*;
//import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
//import io.netty.handler.codec.http.websocketx.WebSocketVersion;
//import io.netty.handler.ssl.SslContext;
//import io.netty.handler.ssl.SslHandler;
//import lombok.extern.slf4j.Slf4j;
//
//import java.net.URI;
//import java.nio.charset.Charset;
//import java.util.concurrent.atomic.AtomicBoolean;
//
//import static com.coldlz.mmp.proxy.handlerserver.ConnectHandler.httpServerCodecName;
//
///**
// * 当接收到 connect 请求时，会将该 handler 放入 pipeline 里面
// */
//@Slf4j
//public class ServerConnectSelectorHandler extends ChannelInboundHandlerAdapter {
//    final UserContext userContext;
//
//    public ServerConnectSelectorHandler(UserContext userContext) {
//        this.userContext = userContext;
//    }
//
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
//        ProxyInfo info = userContext.getProxyInfo();
//        if (info.getProtocolName() != null) {
//            throw new RuntimeException("处理异常,本handler只用于判断协议");
//        }
//        if (obj instanceof ByteBuf msg) {
//            int len = msg.readableBytes();
//            if (len == 0) {
//                return;
//            }
//            // 尝试解析
//            int startIndex = msg.readerIndex();
//            ChannelPipeline pipeline = ctx.pipeline();
//            byte[] contentBytes = new byte[len];
//            msg.readBytes(contentBytes);
//
//            String content = new String(contentBytes, Charset.defaultCharset());
//            String[] contents = content.split("\r\n");
//            if (pipeline.get(SslHandler.class) == null) {
//                if (content.startsWith("GET")
//                        || content.startsWith("POST")
//                        || content.startsWith("PUT")
//                        || content.startsWith("DELETE")
//                        || content.startsWith("OPTIONS")
//                        || content.startsWith("HEAD")
//                        || content.startsWith("PATCH")
//                        || content.startsWith("TRACE")
//                        || content.startsWith("CONNECT")
//                ) {
//                    // 明文，且在前面已接收到 connect 请求，因此这里是 ws 协议
//                    info.setProtocolName(Protocol.WS);
//                    // 获取webSocket版本
//                    URI webSocketUri = new URI(contents[0].split(" ")[1]);
//                    info.setWebSocketURI(webSocketUri);
//                    WebSocketVersion webSocketVersion = parseWebSocketVersion(contents);
//                    info.setWebSocketVersion(webSocketVersion);
//                    info.setHandshakeInfo(contentBytes);
//
//                    pipeline.addLast(httpServerCodecName, new HttpServerCodec());
//                    pipeline.addLast(new WebSocketServerProtocolHandler(webSocketUri.toString()));
//                    pipeline.addLast(new ServerProxyHttpHandler(userContext));
//
//                    removeSelfAndFireRead(ctx, msg, pipeline, startIndex);
//                } else {
//                    // 密文，且在前面已接收到 connect 请求，可能是 wss 协议 或者 https 协议
//                    // 移除本 handler 重新加入 sslHandler + 本handler 重新判断
//                    SslContext serverSsl = SslContextManager.getServerSsl(info.getHost());
//                    SslHandler sslHandler = serverSsl.newHandler(ctx.alloc());
//                    pipeline.addLast(sslHandler);
//                    pipeline.addLast(new ServerConnectSelectorHandler(userContext));
//                    // 重置读取的信息
//                    removeSelfAndFireRead(ctx, msg, pipeline, startIndex, false);
//                }
//            } else {
//                // 已经加入过 sslHandler 表示是第二次处理判断，此时数据已经解密了
//                Protocol protocol = wssOrHttps(ctx, contents);
//                info.setProtocolName(protocol);
//
//                if (protocol == Protocol.HTTPS) {
//                    // 在前面已经放过了sslHandler
//                    pipeline.addLast(httpServerCodecName, new HttpServerCodec());
//                    pipeline.addLast(new ServerProxyHttpHandler(userContext));
//                } else if (protocol == Protocol.WSS) {
//                    URI webSocketUri = new URI(contents[0].split(" ")[1]);
//                    info.setWebSocketURI(webSocketUri);
//                    WebSocketVersion webSocketVersion = parseWebSocketVersion(contents);
//                    info.setWebSocketVersion(webSocketVersion);
//                    info.setHandshakeInfo(contentBytes);
//                    pipeline.addLast(httpServerCodecName, new HttpServerCodec());
//                    pipeline.addLast(new WebSocketServerProtocolHandler(webSocketUri.toString()));
//                    pipeline.addLast(new ServerProxyHttpHandler(userContext));
//                } else {
//                    throw new RuntimeException("参数异常");
//                }
//                removeSelfAndFireRead(ctx, msg, pipeline, startIndex);
//            }
//        } else {
//            throw new RuntimeException("类型异常");
//        }
//    }
//
//    private void removeSelfAndFireRead(ChannelHandlerContext ctx, ByteBuf msg, ChannelPipeline pipeline, int startIndex) {
//        removeSelfAndFireRead(ctx, msg, pipeline, startIndex, true);
//    }
//
//    private void removeSelfAndFireRead(ChannelHandlerContext ctx, ByteBuf msg, ChannelPipeline pipeline
//            , int startIndex, boolean iniClientChannel) {
//        removeSelf(ctx, pipeline);
//        if (iniClientChannel) {
//            RemoteClient client = RemoteClientFactory.getClient(userContext);
//            // 配置编解码器
//            client.getClientChannelInitializer().reinitializeChannel(client.getRemoteChannel());
//            ProxyInfo info = userContext.getProxyInfo();
//            Protocol protocolName = info.getProtocolName();
//            if (protocolName == Protocol.WS || protocolName == Protocol.WSS) {
//                // 发送握手信息
//                parseContentAndHandshake(info, client);
//            }
//            msg.readerIndex(startIndex);
//            pipeline.fireChannelRead(msg);
//        } else {
//            msg.readerIndex(startIndex);
//            pipeline.fireChannelRead(msg);
//        }
//    }
//
//    private static void parseContentAndHandshake(ProxyInfo info, RemoteClient client) {
//        String content = new String(info.getHandshakeInfo());
//        String[] contents = content.split("\r\n");
//        String firstContent = contents[0];
//        String httpMethod = firstContent.split("")[2];
//        String uri = info.getWebSocketURI().toString();
//
//        // 封装请求，并将请求转发
//        FullHttpRequest request = new WebSocketHandshakeRequest(HttpVersion.valueOf(info.getHttpVersion())
//                , HttpMethod.valueOf(httpMethod), uri);
//        if (contents.length > 1) {
//            for (int i = 1; i < contents.length; i++) {
//                String str = contents[i];
//                int j = str.indexOf(":");
//                if (j < 0) {
//                    continue;
//                }
//                String k = str.substring(0, j);
//                String v = str.substring(j + 1);
//                request.headers().add(k, v.trim());
//            }
//        }
//        try {
//            AtomicBoolean success = new AtomicBoolean(false);
//            client.writeAndFlush(request, future -> {
//                if (future.isSuccess()) {
//                    success.set(true);
//                    log.info("握手成功");
//                } else {
//                    log.error("握手失败", future.cause());
//                }
//            }).sync();
//            if (!success.get()) {
//                throw new RuntimeException("ws握手失败");
//            }
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//
//    private WebSocketVersion parseWebSocketVersion(String[] contents) {
//        for (String content : contents) {
//            if (content.startsWith("Sec-WebSocket-Version: ")) {
//                String versionStr = content.split(":")[1];
//                versionStr = versionStr.trim();
//                int version = Integer.parseInt(versionStr);
//                return switch (version) {
//                    case 13 -> WebSocketVersion.V13;
//                    case 8 -> WebSocketVersion.V08;
//                    case 7 -> WebSocketVersion.V07;
//                    case 0 -> WebSocketVersion.V00;
//                    default -> WebSocketVersion.UNKNOWN;
//                };
//            }
//        }
//        log.warn("解析webSocket版本失败");
//        return WebSocketVersion.UNKNOWN;
//    }
//
//    private void removeSelf(ChannelHandlerContext ctx, ChannelPipeline pipeline) {
//        if (!ctx.isRemoved()) {
//            pipeline.remove(this);
//        }
//    }
//
//
//    private Protocol wssOrHttps(ChannelHandlerContext ctx, String[] contents) {
//        for (String cnt : contents) {
//            if (cnt.equals("Upgrade: websocket")) {
//                return Protocol.WSS;
//            }
//        }
//        return Protocol.HTTPS;
//    }
//}
